#include "precompile.h"
#include "base_bin.h"
#include "base_util.h"

_SSL_BEGIN
_SSBASEL_BEGIN

ssbin::ssbin()
{
	ptr_ = NULL;
	bin_size_ = 0;
	allocat_size_ = 0;
}

ssbin::ssbin(const ssbin &b)
{
	allocat_size_ = b.bin_size_;
	bin_size_ = b.bin_size_;
	ptr_ = (unsigned char *)malloc(allocat_size_);
	memcpy(ptr_, b.ptr_, bin_size_);
}

ssbin::~ssbin()
{
	clear();
}

unsigned char *ssbin::alloc_ptr(size_t sz)
{
	SS_VERIFY(makesure_buffer_is_enough(sz));
	return ptr();
}

bool ssbin::set_size(size_t new_size)
{
	if(new_size > allocat_size_)
		return false;
	bin_size_ = new_size;
	return true;
}

unsigned char *ssbin::ptr() const
{
	return ptr_;
}

size_t ssbin::size() const
{
	return bin_size_;
}

unsigned char* ssbin::detach(size_t *sz)
{
	if(sz != NULL)
		*sz = bin_size_;
	bin_size_ = 0;
	unsigned char *ret = ptr_;
	ptr_ = NULL;
	allocat_size_ = 0;
	return ret;
}

void ssbin::clear()
{
	free(ptr_);
	ptr_ = NULL;
	bin_size_ = 0;
	allocat_size_ = 0;
}

ssbin& ssbin::operator=(const ssbin& b)
{
	memcpy(alloc_ptr(b.bin_size_), b.ptr_, b.bin_size_);
	return *this;
}


bool ssbin::makesure_buffer_is_enough(size_t sz)
{
	if(sz + 1 < allocat_size_)
	{
		return true;
	}

	int new_allocate_size = (sz + 10) * 2;
	unsigned char *new_ptr = (unsigned char*)realloc(ptr_, new_allocate_size);
	if(new_ptr == NULL)
	{
		return false;
	}
	ptr_ = new_ptr;
	allocat_size_ = new_allocate_size;
	return true;
}

_SSBASEL_END
_SSL_END
